﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using NHibernate.Connection;
using Trends.TFC.Data;

namespace DaCredito
{

    public enum TiposGeracaoCodigo
    {
        TabelaDeMaximos, Surrogate, SurrogateUnico
    };

    public enum Sistemas
    {
        Academico = 1,
        Financeiro = 2,
        Acervo = 3,
        Curriculo = 4,
        Questionario = 5,
        Diario = 6,
        Tramite = 7,
        Carne = 8,
        Registro = 10,
        Concurso = 17,
        RecursosHumanos = 18,
        Portal = 20,
        ProdeCar = 21,
        Financeiro3 = 25,
        Acervo3 = 26,
        Contratos = 33,
        Folha = 34,
        ControleProducao = 35,
        ControlePonto = 36,
        SAC = 37
    };

    public class GerarCodigo
    {

        private string isPrefixoTabela;
        private TiposGeracaoCodigo ieTipoGeracaoCodigo = TiposGeracaoCodigo.TabelaDeMaximos;
        private int iiIncremento = 1;
        private Sistemas ieCodigoSistema;
        private int iiCodigoSistema = 0;
        private Connection ioDb;

        public GerarCodigo(Connection aoConnection)
        {
            ioDb = aoConnection;
        }

        public GerarCodigo(string aslsDBMSName, string asConnectionString)
        {
            ioDb = new Connection(aslsDBMSName);
            ioDb.ConnectionString = asConnectionString;
        }

        public string PrefixoTabela
        {
            get { return this.isPrefixoTabela; }
            set { this.isPrefixoTabela = value; }
        }

        public TiposGeracaoCodigo TipoGeracaoCodigo
        {
            get { return this.ieTipoGeracaoCodigo; }
            set { this.ieTipoGeracaoCodigo = value; }
        }

        public int Incremento
        {
            get { return this.iiIncremento; }
            set { this.iiIncremento = value; }
        }

        public Sistemas Sistema
        {
            get { return ieCodigoSistema; }
            set
            {
                ieCodigoSistema = value;
                iiCodigoSistema = Convert.ToInt16(value);
            }
        }

        /// <summary>
        /// Inicia o objeto, chamando a função para gerar um novo código.
        /// </summary>
        /// <remarks>
        /// A princípio apenas uma forma de gração de código está implementada,
        /// usando uma tabela de máximos (SQN_sequencia). Posteriormente, 
        /// outras formas de geração de código automático podem ser impementadas
        /// neste objeto, bastando apenas criar a função e definir um tipo de identificação
        /// para ela. Seja qual for a forma de geração de código utilizada.
        /// </remarks>
        /// <returns></returns>
        public double Gerar()
        {
            //this.Check(this.PrefixoTabela, "PrefixoTabela");
            switch (this.ieTipoGeracaoCodigo)
            {
                case TiposGeracaoCodigo.TabelaDeMaximos:
                    // Chama a função para gerar código novo usando uma tabela de máximos (SQN_sequencia)
                    return this.GerarCodigoSQN();

                case TiposGeracaoCodigo.Surrogate:
                    return this.GerarSurrogate();

                case TiposGeracaoCodigo.SurrogateUnico:
                    return this.GerarSurrogateUnico();

                default: // Não está previsto receber este argumento
                    throw new TFCException("teste");
            }
        }

        private double GerarSurrogate()
        {
            double ldbCodigo = GerarCodigoSQN();
            double liSite = GetSite();
            return (1000000000 * liSite) + ldbCodigo;
        }

        private double GerarSurrogateUnico()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private double GerarCodigoSQN()
        {
            double ldbCodigo = 0;
            this.Db.Open();
            this.Db.BeginTransaction();
            try
            {
                // Atualizar a tabela de máximos com o valor incrementado
                this.AtualizarSQN();
                // Obtém o valor do novo código da tabela de máximos
                ldbCodigo = this.GetCodigoSQN();
                //this.Db.Commit();
            }
            catch (Exception ex)
            {
                //this.Db.Rollback();
                throw ex;
            }
            finally
            {
                this.Db.Close();
            }
            return ldbCodigo;
        }

        /// <summary>
        /// Atualiza o valor do código sequencial na tabela SQN_sequencia 
        /// (tabela de máximos) para a tabela que foi informado o prefixo.
        /// </summary>
        private void AtualizarSQN()
        {
          /*  IDataParameter loCodigoSistema = this.Db.CreateParameter("codigo_sistema",
              this.iiCodigoSistema);
            IDataParameter loPrefixoTabela = this.Db.CreateParameter("prefixo_tabela",
              this.isPrefixoTabela);
            IDataParameter loIncremento = this.Db.CreateParameter("incremento",
              this.iiIncremento);

            //Segura o registro - ninguém mais pode acessá-lo
            int liCount = this.Db.ExecSql(this.GetSQL("sqlAtualizarSQN"), loPrefixoTabela, loCodigoSistema);

            // Verifica se existe ocorrência da tabela em SQN_sequencia
            if (liCount == 0)
                // Se não existe ocorrência em SQN_sequencia para o sistema/tabela,
                // insere uma ocorrência
                this.Db.ExecSql(this.GetSQL("sqlInsertSQN"), loPrefixoTabela, loCodigoSistema, loIncremento);
            else
                // Atualiza a tabela SQN_sequencia
                this.Db.ExecSql(this.GetSQL("sqlUpdateSQN"), loPrefixoTabela, loCodigoSistema, loIncremento);
        */}

        private double GetCodigoSQN()
        {
            /*IDataParameter loCodigoSistema = this.Db.CreateParameter("codigo_sistema",
              this.iiCodigoSistema);
            IDataParameter loPrefixoTabela = this.Db.CreateParameter("prefixo_tabela",
              this.isPrefixoTabela);
            double ldbCodigo = 0;
            this.Db.SelectInto(this.GetSQL("sqlGetCodigoSQN"), new IDataParameter[] {
        loPrefixoTabela, loCodigoSistema }, out ldbCodigo);
            return ldbCodigo;*/
            return 0;
        }

        private string GetSQL(string asKey)
        {
            string lsPrefix;
            if (this.iiCodigoSistema != 0)
                lsPrefix = "1";
            else
                lsPrefix = "2";
            return "teste"; // GerarCodigoRes.ResourceManager.GetString(asKey + lsPrefix);
        }

        private Connection Db
        {
            get
            {
                return this.ioDb;
            }
        }

        private double GetSite()
        {
            string lsSQL = "teste"; //GerarCodigoRes.sqlGetCodigoSite;

            int liCodigo = 0;
            string lsCodigo;

            this.Db.Open();

            try
            {
                //this.Db.SelectInto(lsSQL, out lsCodigo);
                lsCodigo = "teste";
                liCodigo = Convert.ToInt16(lsCodigo.TrimEnd());
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                this.Db.Close();
            }

            return Convert.ToDouble(liCodigo);

        }

    } // GerarCodigo

} // Trends.TFC.Web.Portal.Services
